package com.mobile.mobilehardware.memory;

import com.mobile.mobilehardware.utils.Logs;
import ohos.aafwk.ability.SystemMemoryInfo;
import ohos.app.Context;
import ohos.app.Environment;
import ohos.data.usage.DataUsage;
import ohos.data.usage.MountState;
import ohos.data.usage.StatVfs;
import ohos.data.usage.Volume;
import ohos.storageinfomgr.StorageInfoManager;
import ohos.utils.zson.ZSONObject;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.List;
import java.util.Locale;
import java.util.Optional;
import java.util.UUID;

import static com.mobile.mobilehardware.utils.MemoryUnit.formatMemoryData;

/**
 * @author guxiaonian
 */
class MemoryInfo {
    private static final String TAG = MemoryInfo.class.getSimpleName();

    /**
     * info
     *
     * @param context Application context
     * @return fill memory info
     */
    static ZSONObject memoryInfo(Context context) {
        MemoryBean memoryBean = new MemoryBean();
        try {
            memoryBean.setRamMemory(getTotalMemory(context));
            memoryBean.setRamAvailMemory(getAvailMemory(context));
            memoryBean.setRomMemoryAvailable(getRomSpace(context));
            memoryBean.setRomMemoryTotal(getRomSpaceTotal(context));
            memoryBean.setSdCardMemoryAvailable(getSdcardSize(context));
            memoryBean.setSdCardMemoryTotal(getSdcardSizeTotal(context));
            memoryBean.setSdCardRealMemoryTotal(getRealStorage(context));
        } catch (Exception e) {
            Logs.i(TAG, e.toString());
        }
        return memoryBean.toJSONObject();
    }

    /**
     * total
     *
     * @param context Application context
     * @return Total memory of phone
     */
    private static String getTotalMemory(Context context) {
        String str1 = "/proc/meminfo";
        String str2;
        String[] arrayOfString;
        long initial_memory = 0;
        try {
            FileReader localFileReader;

            localFileReader = new FileReader(str1);

            BufferedReader localBufferedReader = new BufferedReader(localFileReader, 8192);
            str2 = localBufferedReader.readLine();

            arrayOfString = str2.split("\\s+");
            //noinspection StatementWithEmptyBody
            for (String num : arrayOfString) {
            }

            initial_memory = Long.parseLong(arrayOfString[1]) * 1000;
            localBufferedReader.close();

        } catch (Exception e) {
            Logs.i(TAG, e.toString());
        }
        return formatMemoryData(initial_memory);
    }

    /**
     * 获取openharmony当前可用内存大小
     *
     * @param context Application context
     * @return availbale memory
     */
    private static String getAvailMemory(Context context) {
        SystemMemoryInfo systemMemoryInfo = new SystemMemoryInfo();
        context.getAbilityManager().getSystemMemoryInfo(systemMemoryInfo);
        return formatMemoryData(systemMemoryInfo.getAvailSysMem());
    }

    /**
     * rom
     *
     * @param context Application Context
     * @return Ram space
     */
    private static String getRomSpace(Context context) {
        File path = context.getDataDir();
        StatVfs stat = new StatVfs(path.getPath());
        return formatMemoryData(stat.getAvailableSpace());
    }

    private static String getRomSpaceTotal(Context context) {
        File path = context.getDataDir();
        StatVfs stat = new StatVfs(path.getPath());
        return formatMemoryData(stat.getSpace());
    }


    /**
     * sd is null ==rom
     *
     * @param context Application context
     * @return sdcard size
     */
    private static String getSdcardSize(Context context) {

        File path = context.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS);
        StatVfs stat = new StatVfs(path.getPath());
        return formatMemoryData(stat.getAvailableSpace());
    }

    private static String getSdcardSizeTotal(Context context) {
        File path = context.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS);
        int subpathindex = path.getAbsolutePath().indexOf("/emulated/0/");
        if (subpathindex > 0) {
            subpathindex += "/emulated/0/".length();
        }
        if (subpathindex >= 0 && path.getAbsolutePath().contains("/storage/")) {
            File sdpath = new File(path.getAbsolutePath().substring(0, subpathindex));
            StatVfs stat = new StatVfs(sdpath.getPath());
            return formatMemoryData(stat.getSpace());
        }
        return "unknown";
    }

    private static String getRealStorage(Context context) {
        long total = 0L;
        Optional<List<Volume>> optGetVolumeInfo = DataUsage.getVolumes();
        if (optGetVolumeInfo.isPresent()) {
            List<Volume> getVolumeInfo = optGetVolumeInfo.get();
            for (Volume obj : getVolumeInfo) {
                long totalSize = 0L;
                if (obj.getState() == MountState.DISK_MOUNTED) {
                    totalSize = getTotalSize(context, obj.getVolUuid());
                    total += totalSize;
                }
            }
        }
        return getUnit(total, 1000);
    }

    private static String[] units = {"B", "KB", "MB", "GB", "TB"};

    /**
     * 进制转换
     * @param base base value
     * @param size size to convert
     * @return get unit
     */
    public static String getUnit(float size, float base) {
        int index = 0;
        while (size > base && index < 4) {
            size = size / base;
            index++;
        }
        return String.format(Locale.getDefault(), "%.2f %s ", size, units[index]);
    }

    /**
     * @param context Application context
     * @param fsUuid fsUuid
     * @return size of the volume
     * 获取总共容量大小，包括系统大小
     */
    public static long getTotalSize(Context context, String fsUuid) {
        try {
            UUID id = UUID.fromString(fsUuid);
            StorageInfoManager stats = StorageInfoManager.newInstance(context);
            return stats.getWholeSize(id);
        } catch (IOException e) {
            e.printStackTrace();
            return -1;
        }
    }
}
